import json
import logging
from datetime import datetime
import sqlglot
import sqlglot.expressions as exp

class HelperFunctions:
    """工具函数类
    提供通用的辅助功能
    """
    @staticmethod
    def validate_json(data):
        """验证数据是否为有效的JSON格式
        
        Args:
            data: 要验证的数据
            
        Returns:
            dict: 解析后的JSON数据，如果不是有效JSON则返回None
        """
        if isinstance(data, str):
            try:
                return json.loads(data)
            except json.JSONDecodeError:
                logging.error("数据不是有效的JSON格式")
                return None
        elif isinstance(data, dict):
            return data
        return None
    
    @staticmethod
    def format_datetime(dt=None, format_str="%Y-%m-%d %H:%M:%S"):
        """格式化日期时间
        
        Args:
            dt (datetime, optional): 要格式化的日期时间对象，默认为当前时间
            format_str (str, optional): 格式化字符串，默认为"%Y-%m-%d %H:%M:%S"
            
        Returns:
            str: 格式化后的日期时间字符串
        """
        if dt is None:
            dt = datetime.now()
        return dt.strftime(format_str)
    
    @staticmethod
    def sanitize_sql(sql):
        """清理SQL语句，移除可能的危险操作
        
        Args:
            sql (str): 要清理的SQL语句
            
        Returns:
            str: 清理后的SQL语句
        """
        # 这里可以添加更复杂的SQL清理逻辑
        # 当前只是一个简单的示例，实际应用中需要更严格的SQL注入防护
        dangerous_keywords = ["DROP", "ALTER", "TRUNCATE", "INSERT", "UPDATE", "DELETE"]
        sql_upper = sql.upper()
        
        for keyword in dangerous_keywords:
            if keyword in sql_upper:
                logging.warning(f"检测到危险的SQL关键字: {keyword}")
                # 在实际应用中，可能需要抛出异常或拒绝执行
        
        return sql
    
    @staticmethod
    def truncate_text(text, max_length=200):
        """截断文本到指定长度
        
        Args:
            text (str): 要截断的文本
            max_length (int, optional): 最大长度，默认为200
            
        Returns:
            str: 截断后的文本
        """
        if len(text) > max_length:
            return text[:max_length] + "..."
        return text

    @staticmethod
    def get_columns_name(sql: str) -> list:
        """获取SQL语句中的列名
        
        Args:
            sql (str): 要解析的SQL语句
            
        Returns:
            list: 包含所有列名的列表
        """
        try:
            # 解析SQL（支持PostgreSQL方言）
            parsed = sqlglot.parse_one(sql, read="postgres")
            select_expressions = parsed.expressions  # 获取SELECT子句中的所有表达式
            columns = []
            
            for expr in select_expressions:
                # 1. 处理带别名的列（如 "name AS username" 或 "name username"）
                if isinstance(expr, exp.Alias):
                    alias = expr.alias_or_name  # 取别名
                    columns.append(alias)
                
                # 2. 处理函数/表达式（如 "COUNT(*)"、"DATE(create_time)"）
                elif isinstance(expr, exp.Func):  # 新版本中函数调用用Func表示
                    # 有别名则用别名，否则用函数表达式字符串（如 "COUNT(*)"）
                    alias = expr.alias_or_name if hasattr(expr, "alias_or_name") else str(expr)
                    columns.append(alias)
                
                # 3. 处理通配符（如 "*" 或 "table.*"）
                elif isinstance(expr, exp.Star):
                    #columns.append("*")  # 通配符标记
                    logging.info("检测到通配符 '*',返回空列")
                    columns = []
                
                # 4. 处理普通列（如 "id" 或 "table.name"）
                elif isinstance(expr, exp.Column):
                    columns.append(expr.name)  # 取列名（忽略表前缀）
                
                # 5. 处理子查询作为列（如 "(SELECT ...) AS sub_col"）
                elif isinstance(expr, exp.Subquery):
                    # 若有别名则用别名，否则用子查询字符串（简化处理）
                    alias = expr.alias_or_name if hasattr(expr, "alias_or_name") else "subquery_result"
                    columns.append(alias)
                
                # 6. 其他未覆盖的情况（转为字符串作为列名）
                else:
                    columns.append(str(expr))
            
            return columns
        
        except Exception as e:
            logging.error(f"get_select_columns SQL解析失败: {e}")
            return []